#ifndef  BT_MUTEX_H
#define  BT_MUTEX_H

#ifdef WIN32
#define _WIN32_WINNT 0x0500
#include <WinSock2.h>
#include <Windows.h>
#endif

#ifdef LINUX
#include <pthread.h>

#endif
#include "sndaconfig.h"

#include <iostream>
using namespace std;

class cond_block;

class mutex_block
{
    public:
        void lock();

        bool trylock();

        void unlock();
        mutex_block(std::string name = "");
        virtual ~mutex_block();
        void set_name(std::string name);

        void wait_signt(cond_block *, UINT32 t = 10);     // �ȴ�ĳ���źŹ���
        void board_signt(cond_block *);                      // ��ĳ�����������ź�
#ifdef WIN32
                CRITICAL_SECTION * get_mutex()
                {   
                    return &m_mutex;
                }
#endif
    private:
#ifdef WIN32
        CRITICAL_SECTION m_mutex;
        //HANDLE   m_mutex;
#endif
        unsigned int locks;
        std::string name;
#ifdef LINUX
        pthread_mutex_t m_mutex;
#endif
};

bool try_lock(mutex_block *);

class mutex_guard
{
        
    public:
        mutex_guard(mutex_block * p)
        {
            m_block = p;
            m_block->lock();
        }
        virtual ~mutex_guard()
        {
            m_block->unlock();
        }
        
        void lock()
        {
            m_block->lock();
        }
        
        void unlock()
        {
            m_block->unlock();
        }
        
        void wait_signt(cond_block *m, UINT32 t = 10)
        {
            m_block->wait_signt(m, t);
        }
        void board_signt(cond_block *m)
        {
            m_block->board_signt(m);
        }
    private:
        mutex_block * m_block;
};

class cond_block
{
    public:
        cond_block(std::string);
        virtual ~cond_block();
    public:
#ifdef LINUX
        pthread_cond_t m_cond;
#endif
        
#ifdef WIN32
        HANDLE m_cond;
#endif
        std::string name;
};

#endif

